<template>
  <div
    class="toolbar-btn-container"
    :class="[autoCalculated ? 'toolbar-btn-calculated' : '']"
    :style="bodyStyle">
    <div v-if="autoCalculated" ref="hidenBtns" class="btn-container-hiden">
      <ButtonItem
        v-bind="$props"
        :item="item"
        :isShowIcon="isShowIcon"
        :isShowText="isShowText"
        :class="btnDisplayMode==='2'?'btn-text-model':''"
        :getBtnType="getBtnType"
        :getIconColor="getIconColor"
        :handleClick="handleClick"
        :iconFontBtns="iconFontBtns"
        :btnDisplayMode="btnDisplayMode"
        :key="item.id"
        :btnSize="btnSize"
        v-for="item in showBtnList">
      </ButtonItem>
    </div>

    <a-button
      ref="moreBtn"
      :size="btnSize"
      :class="[
        'more-btn',
        'btn-container-more-btn-hiden',
        { 'more-link-btn': getBtnType({}) === 'link' }
      ]"
      :type="getBtnType({})">
      <i v-if="isShowIcon" :class="['syIcon sy-more-fill', { 'suffix-icon': isShowText }]" />
      <template v-if="isShowText">{{ $i18n('common.more.label') }}</template>
    </a-button>
    <div
      class="btn-container"
      :style="{ maxWidth: maxWidth, maxHeight: maxHeight, flexWrap: isWrap ? 'wrap' : 'nowrap' }">
      <ButtonItem
        v-bind="$props"
        :item="item"
        :class="btnDisplayMode==='2'?'btn-text-model':''"
        :isShowIcon="isShowIcon"
        :isShowText="isShowText"
        :getBtnType="getBtnType"
        :getIconColor="getIconColor"
        :handleClick="handleClick"
        :iconFontBtns="iconFontBtns"
        :iconSvgBtns="iconSvgBtns"
        :btnDisplayMode="btnDisplayMode"
        :key="item.id"
        :btnSize="btnSize"
        v-for="item in displayBtnList">
      </ButtonItem>
    </div>
    <a-dropdown v-if="dropdownBtnList.length" :placement="dropPlacement">
      <a-menu slot="overlay" class="dropdown-menu-container">
        <template v-for="item in dropdownBtnList">
          <CommentSearch v-if="item.id === 'commentSearch'" :key="item.id + 1" placement="right">
            <template v-slot="slotProps">
              <a-menu-item
                :disabled="item.disable"
                class="menu-item-wrapper"
                @click.native="slotProps.click">
                <i
                  v-if="isShowIcon"
                  :class="[item.icon, { 'suffix-icon': isShowText }]"
                  :style="`color: ${item.color}`" />
                <template v-if="isShowText">{{ item.name }}</template>
              </a-menu-item>
            </template>
          </CommentSearch>
          <a-menu-item
            v-else
            :key="item.id"
            :disabled="item.disable"
            @click="handleClick(item)">
            <template v-if="isShowIcon">
              <i
                v-if="!iconFontBtns.includes(item.icon)"
                :class="[item.icon, { 'suffix-icon': isShowText }]"
                :style="`color: ${item.color}`" />
              <icon-font v-else :type="item.icon" style="font-size: 16px" />
            </template>
            <a-tooltip :title="item.name.length > 6 ? item.name : ''" placement="right">
              <template v-if="isShowText || btnDisplayMode === '1'">{{ item.name }}</template>
            </a-tooltip>
          </a-menu-item>
        </template>
      </a-menu>
      <a-button
        :size="btnSize"
        :class="['more-btn', { 'more-link-btn': getBtnType({}) === 'link' }]"
        :type="getBtnType({})">
        <i v-if="isShowIcon" :class="['syIcon sy-more-fill', { 'suffix-icon': isShowText }]" />
        <template v-if="isShowText">{{ $i18n('common.more.label') }}</template>
      </a-button>
    </a-dropdown>
  </div>
</template>

<script>
  import { mapActions, mapState, mapWritableState } from 'pinia';
  import Stateful from '@/layout/widgets/stateful';
  import { useSrcCacheStore } from '@/store/modules/src-cache';
  import orderHandle from '@/components/classic-layout/summary/header/mixin/handle';
  import { fireEvent } from '@/handles/common/sdk';
  import globalData from '@/plugins/data';
  import globalMethods from '@/plugins/methods';
  import handleObj, { doHandle } from '@/handles/handle-list/summary';
  import { useSummaryCommentStore } from '@/store/modules/summary/comment';
  import ButtonItem from './components/ButtonItem.vue';
  import emitter from "@/plugins/global-callback";

  // 按钮展示模式
  const btnDisplayModeMap = {
    icon: '1', // 图标
    text: '2', // 文字
    iconAndText: '3' // 图标 + 文字
  };
  export default {
    name: 'ToolbarButton',
    mixins: [Stateful, orderHandle],
    components: {
      ButtonItem
    },
    props: {
      autoMaxCount: {
        type: Number,
        default: 0
      },
      autoCalculated: {
        // 自动计算
        type: Boolean,
        default: false
      },
      showBtnIds: {
        // 要显示的按钮id
        type: Array,
        default: () => []
      },
      maxDisplayBtnCount: {
        // 最多展示多少个按钮，剩余的按钮统一收起来
        type: Number,
        default: Infinity,
        validator: (value) => value >= 0
      },
      btnDisplayMode: {
        type: String,
        default: btnDisplayModeMap.iconAndText,
        validator: (value) =>
          [btnDisplayModeMap.icon, btnDisplayModeMap.text, btnDisplayModeMap.iconAndText].includes(
            value
          )
      },
      btnSize: {
        // 按钮大小
        type: String,
        default: 'default',
        validator: (value) => ['small', 'default', 'large'].includes(value)
      },
      isBtnMode: {
        // 是否为按钮模式，另一种模式为非按钮的link模式
        type: Boolean,
        default: true
      },
      maxWidth: {
        // 容器最大宽度
        type: String,
        default: '100%'
      },
      maxHeight: {
        // 容器最大高度
        type: String,
        default: '100%'
      },
      isWrap: {
        // 是否换行
        type: Boolean,
        default: true
      },
      dropPlacement: {
        //更多下拉菜单展示位置
        type: String,
        default: 'bottomLeft',
        validator: (value) =>
          [
            'bottomLeft',
            'bottomCenter',
            'bottomRight',
            'topLeft',
            'topCenter',
            'topRight'
          ].includes(value)
      },
      scrollMaxHeight: {
        // 下拉滚动容器最大高度
        type: Number,
        default: 160
      },
      lastOut:{
        //最后一个元素不放入更多
        type:Boolean,
        default:false,
      }
    },
    computed: {
      ...mapState(useSummaryCommentStore, ['attitude']),
      ...mapWritableState(useSummaryCommentStore, ['isPigeonhole']),
      ...mapState(useSummaryCommentStore, ['trackSet']),
      isTrack() {
        return this.trackSet.isTrack;
      },
      orderBtnList() {
        return (
          this.baseInfo?.orderButtons.orderButtons.map((item) => {
            const { code, icon, name } = item;
            let newItem = {
              name: globalMethods.i18n(name),
              icon
            };

            if (code === 'favorite') {
              const { hasFavorite } = this.baseInfo.businessData.affair;

              newItem = {
                name: globalMethods.i18n(
                  hasFavorite ? 'common.cancel.collection.label' : 'common.collection.label'
                ),
                icon: `syIcon ${hasFavorite ? 'sy-collect-fill' : 'sy-collect'}`
              };
            }
            if (code === 'archive') {
              newItem = {
                name: globalMethods.i18n(
                  this.isPigeonhole
                    ? 'collaboration.pageDesigner.archive.cancel'
                    : 'permission.operation.Archive'
                ),
                icon: `${this.isPigeonhole ? 'cap-icon-quxiaoguidang' : 'cap-icon-guidang'}`
              };
            }
            if (code === 'track') {
              newItem = {
                name: globalMethods.i18n('permission.operation.Track'),
                icon: `${this.isTrack ? 'cap-icon-a-genzongshixiang1' : 'cap-icon-genzong'}`
              };
            }
            return {
              ...newItem,
              id: code,
              handle: code,
              eventType: 'order'
            };
          }) || []
        );
      },
      normalBtnList() {
        return this.normalButtonList.map((item) => {
          const { label, image } = item;

          return {
            ...item,
            name: label,
            icon: image
          };
        });
      },
      advancedBtnList() {
        return this.advancedButtonList.map((item) => {
          const { id, label, image, handle } = item;

          return {
            ...item,
            id: id || handle,
            name: label,
            icon: image
          };
        });
      },
      basicBtnList() {
        return [...(this.basicButtonList[0] || []), ...(this.basicButtonList[1] || [])].map(
          (item) => {
            const { id, label, image, handle } = item;

            return {
              ...item,
              id: id || handle,
              name: label,
              icon: image
            };
          }
        );
      },
      allBtnList() {
        return [
          ...this.orderBtnList,
          ...this.normalBtnList,
          ...this.advancedBtnList,
          ...this.basicBtnList
        ];
      },
      allBtnMap() {
        return new Map(this.allBtnList.map((item) => [item.id || item.handle, item]));
      },
      allHandleBtnMap() {
        return new Map(this.allBtnList.map((item) => [item.handle, item]));
      },
      showBtnList() {
        if (!this.showBtnIds || !this.showBtnIds.length) return [];
        let btns = this.showBtnIds.filter(id => !this.hiddenBtnList.includes(id))
          .map((id) => this.allBtnMap.get(id) || this.allHandleBtnMap.get(id))
          .filter((item) => {
            if (item) {
              // 撤销回退状态不展示即时会议
              if (this.baseInfo.businessData.affair.state === 6 && item.id === 'meetingInstant') {
                return false;
              }
              return true;
            }
            return false;
          });
        return btns;
      },
      maxShowBtnCount() {
        if (this.autoCalculated) {
          return this.autoCalculatedMaxDisplayBtnCount;
        } else {
          return this.maxDisplayBtnCount <= this.showBtnList.length
            ? this.maxDisplayBtnCount
            : this.showBtnList.length;
        }
      },
      displayBtnList() {
        let slice = this.showBtnList.slice(0, this.maxShowBtnCount);
        if (this.lastOut) {
          if (slice.length + 1 === this.showBtnList.length) {
            return this.showBtnList;
          }
        }
        return slice;
      },
      dropdownBtnList() {
        let slice = this.showBtnList.slice(this.maxShowBtnCount);
        if (slice.length===1&&this.lastOut){
          return [];
        }
        return slice;
      },
      isShowIcon() {
        return [btnDisplayModeMap.icon, btnDisplayModeMap.iconAndText].includes(
          this.btnDisplayMode
        );
      },
      isShowText() {
        return [btnDisplayModeMap.text, btnDisplayModeMap.iconAndText].includes(
          this.btnDisplayMode
        );
      }
    },
    data() {
      return {
        autoCalculatedMaxDisplayBtnCount: 0,
        bodyStyle: {},
        //不展示按钮 -- 页面加载禁用机制
        hiddenBtnList:[],
      };
    },
    created() {
      //新的图标要同iconFont
      this.iconFontBtns = [
        'sy-saveDraft',
        'vp-tijiao',
        'sy-save',
        'cap-icon-dayin',
        'cap-icon-shipin2',
        'cap-icon-conference',
        'cap-icon-guidang',
        'cap-icon-quxiaoguidang',
        'sy-Supervisory-monitoring',
        'sy-newworkflowform',
        'cap-icon-a-genzongshixiang1',
        'cap-icon-genzong'
      ];
      //部分svg图标选中后要单独加class
      this.iconSvgBtns = ['cap-icon-quxiaoguidang', 'cap-icon-a-genzongshixiang1'];
      //不展示按钮 -- 页面加载禁用机制
      emitter.subscribe('hiddenBtn-event', (id) => this.hiddenBtnList.push(id));
    },
    mounted() {
      // 需要二次计算宽度，再渲染真正的按钮
      if (this.autoCalculated) {
        this.initResize();
      }
    },
    watch: {
      showBtnIds() {
        this.$nextTick(() => {
          this.initShowBtnsWidth();
        });
      }
    },
    methods: {
      initResize() {
        if (this.autoMaxCount > 0) {
          this.initShowBtnsWidth();
        } else {
          if (!this.isResizeObserver) {
            this.isResizeObserver = true;
            new ResizeObserver(() => {
              this.initShowBtnsWidth();
            }).observe(this.$el);
          } else {
            this.initShowBtnsWidth();
          }
        }
      },
      initShowBtnsWidth() {
        if (!this.$refs.hidenBtns) return;

        let { children } = this.$refs.hidenBtns;
        let rootBrc = this.$el.getBoundingClientRect();
        let moreBrc = this.$refs.moreBtn.$el.getBoundingClientRect();
        let marginRight = 8;
        let rootWidth = rootBrc.width;
        // 获取更多的宽度
        let moreWidth = moreBrc.width;
        let showBtnWidth = 0;
        let showCount = 0;
        let widthList = [];
        if (this.autoMaxCount > 0) {
          for (let i = 0; i < children.length; i++) {
            let cld = children[i].getBoundingClientRect();
            let cldW = cld.width + marginRight;
            widthList.push(cldW);
            showBtnWidth += cldW;
            showCount = i + 1;
            if (this.autoMaxCount > 0 && showCount === this.autoMaxCount) {
              // 还有更多
              // 强制更新bodyStyle
              // console.log("children.length", children.length);
              if (children.length > showCount) {
                this.bodyStyle = { width: showBtnWidth + moreWidth + 'px' };
              } else {
                this.bodyStyle = { width: showBtnWidth + 'px' };
              }
              break;
            }
          }
        } else {
          for (let i = 0; i < children.length; i++) {
            let cld = children[i].getBoundingClientRect();
            let cldW = cld.width + marginRight;
            widthList.push(cldW);
            showBtnWidth += cldW;
            showCount = i + 1;
            if (showBtnWidth > rootWidth) {
              // 第一个就超长了，直接显示更多
              if (i == 0) {
                showCount = 0; // 一个都不显示
              } else {
                // 显示到第几个，由于已经大于了rootWidth 需要回退一个
                // 回退完成后看看剩余宽度能否显示更多
                showCount = showCount - 1;
                showBtnWidth = showBtnWidth - widthList.pop();
                if (moreWidth > rootWidth - showBtnWidth) {
                  // 已经后退到0了，说明是第二个就超长了，并且无法放下更多
                  if (showCount == 0) {
                    showCount = 0;
                  } else {
                    // 还要退一步
                    showCount = showCount - 1;
                    showBtnWidth = showBtnWidth - widthList.pop();
                  }
                }
              }
              break;
            }
          }
        }
        // 结束逻辑
        this.autoCalculatedMaxDisplayBtnCount = showCount;
      },
      // 判断按钮是否为提交类型
      isCommitBtn(btnInfo) {
        const { handle, submitAction } = btnInfo;

        if (handle === 'continueSubmit') return true;

        if (handle === 'custom' && submitAction === 'continueSubmit') return true;

        if (
          handle === 'systemAudit' &&
          ['formAuditPass', 'vouchPass', 'bulletionAuditPass', 'newsAuditPass'].includes(
            submitAction
          )
        )
          return true;

        return false;
      },
      // 获取按钮类型
      getBtnType(btnInfo) {
        if (!this.isBtnMode) return 'link';

        if (this.isCommitBtn(btnInfo)) {
          return 'primary';
        }

        return 'default';
      },
      // 获取图标颜色
      getIconColor(btnInfo) {
        if (!this.isBtnMode) return btnInfo.color;

        if (this.isCommitBtn(btnInfo)) return '';
        return btnInfo.color;
      },
      ...mapActions(useSrcCacheStore, ['createShowWorkFlowUrl']),
      handleClick(btnInfo) {
        const { eventType, handle, clickUrl, type } = btnInfo;
        console.log('toolbar-clicked', handle, btnInfo);
        if (eventType === 'order') {
          this.handle(handle, this.baseInfo.businessData, this.baseInfo, btnInfo);
          return;
        }

        if (type === 'click') {
          const url = clickUrl.includes('//') ? clickUrl : `${globalData.ctxPath}${clickUrl}`;

          window.open(url);
          return;
        }

        this.handleClickBtn(btnInfo);
      },
      async handleClickBtn(btnInfo) {
        let commentIsEmpty =
          !this.commentText || (this.isRichText && this.commentText === '<p></p>');
        // 勾选'不同意时必须填写意见'，提交时必须填写意见
        if (
          this.baseInfo.businessData?.nodePolicy?.disAgreeOpinionPolicy === 1 &&
          btnInfo.handleOriginal === 'ContinueSubmit' &&
          this.attitude === 'disagree' &&
          commentIsEmpty
        ) {
          globalMethods.error({
            content: globalMethods.i18n('collaboration.common.deafult.dealCommentNotNull')
          });
          return;
        }
        // 意见必填
        if (btnInfo.opinionPolicy && commentIsEmpty) {
          globalMethods.error({
            content: globalMethods.i18n('collaboration.common.deafult.dealCommentNotNull')
          });

          return;
        }

        doHandle.call(this, btnInfo.handle, btnInfo);
      },
      dropdownScrollStyle(itemList) {
        if (itemList.length > 15) {
          let height = Math.min(window.innerHeight * 0.7, 500);
          return {
            maxHeight: height + 'px',
            overflowY: 'auto',
            padding: '5px'
          };
        }
      },
      isShowBtn(btnId) {
        // 撤销回退状态不展示即时会议
        if (this.baseInfo.businessData.affair.state === 6 && btnId === 'meetingInstant')
          return false;

        return true;
      }
    }
  };
</script>

<style lang="scss">
  .toolbar-btn-calculated {
    .btn-container {
      overflow: hidden !important;
    }
  }
  .toolbar-btn-container {
    display: flex;
    position: relative;
    .btn-container-hiden {
      overflow: hidden;
      position: absolute;
      background: red;
      height: 0;
      width: 0;
      pointer-events: none;
      z-index: -1;
      visibility: hidden;
    }
    .btn-container-more-btn-hiden {
      visibility: hidden;
      position: absolute;
      left: 0;
      top: 0;
      pointer-events: none;
      z-index: -1;
    }
    .btn-container {
      display: flex;
      overflow: auto;

      button.toolbar-btn-wrapper {
        margin: 8px 8px 0 0;
        display: flex;
        align-items: center;
        &:last-child {
          margin-right: 0;
        }
      }
      button.ant-btn-link {
        &:first-child {
          padding-left: 0;
        }
      }
      button > i.suffix-icon {
        color: #595959 !important;
      }
    }

    .more-btn {
      margin-left: 8px;
      margin-top: 8px;
      display: flex;
      align-items: center;
    }

    .ant-btn-link {
      color: rgba(0, 0, 0, 0.65);
      padding-left: 6px;
    }

    .syIcon.sy-collect-fill {
      color: #1890ff;
      color: var(--theme-brand6, #1890ff);
    }

    .more-link-btn {
      &:hover {
        color: #1890ff;
        color: var(--theme-brand6, #1890ff);
      }
    }
  }

  .suffix-icon {
    margin-right: 5px;
  }

  .menu-item-wrapper {
    display: flex;
    align-items: center;
  }
</style>
<style lang="scss">
  .toolbar-btn-container {
    .ant-btn {
      > span {
        line-height: 0;
      }
      > .anticon {
        line-height: 0;
      }
      &.btn-text-model{
        max-width: 116px;
        > span {
          line-height: 22px;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
      }
    }
    
  }
</style>
<style scoped>
  .dropdown-menu-container {
    max-height: 300px;
    overflow-y: auto;
    width: 150px;
  }

  .dropdown-menu-container >>> .ant-dropdown-menu-item {
    overflow: hidden;
    text-overflow: ellipsis;
    padding-left: 16px;
    padding-right: 16px;
    margin-top: 4px;
  }
</style>